<?php
/**
 * 搜索API主类
 * 负责处理搜索请求和返回结果
 */
class SearchAPI {
    /**
     * @var ConfigManager 配置管理器
     */
    private $configManager;
    
    /**
     * @var CacheManager 缓存管理器
     */
    private $cacheManager;
    
    /**
     * @var HttpClient HTTP客户端
     */
    private $httpClient;
    
    /**
     * 构造函数
     * @param ConfigManager $configManager 配置管理器
     * @param CacheManager $cacheManager 缓存管理器
     * @param HttpClient $httpClient HTTP客户端
     */
    public function __construct(ConfigManager $configManager, CacheManager $cacheManager, HttpClient $httpClient) {
        $this->configManager = $configManager;
        $this->cacheManager = $cacheManager;
        $this->httpClient = $httpClient;
    }
    
    /**
     * 执行搜索
     * @param array $data 搜索参数
     * @return array|bool 搜索结果或失败状态
     */
    public function search($data) {
        // 生成缓存键
        $cacheKey = md5(json_encode($data));
        
        // 尝试从缓存获取结果
        $cachedResult = $this->cacheManager->cache($cacheKey);
        if (!empty($cachedResult)) {
            return $cachedResult;
        }
        
        // 从配置获取搜索结果
        $result = $this->getSearchResult($data);
        
        // 如果搜索成功，缓存结果
        if (!empty($result)) {
            $this->cacheManager->cache($cacheKey, $result);
        }
        
        return $result;
    }
    
    /**
     * 获取搜索结果
     * @param array $data 搜索参数
     * @param int $index 当前尝试的URL索引
     * @return array|bool 搜索结果或失败状态
     */
    private function getSearchResult($data, $index = 0) {
        // 获取当前URL配置
        $urlConfig = $this->configManager->getCurrentUrlConfig();
        
        // 如果当前URL为空，尝试从列表获取
        if (empty($urlConfig)) {
            $urlList = $this->configManager->getUrlList();
            $urlConfig = !empty($urlList[$index]) ? $urlList[$index] : [];
        }
        
        // 如果没有可用的URL，返回失败
        if (empty($urlConfig)) {
            $this->configManager->updateCurrentUrl([]);
            return false;
        }
        
        // 根据格式获取搜索结果
        $result = null;
        if ($urlConfig['format'] == 'json') {
            $result = $this->getResultByJson($urlConfig, $data);
        } else {
            $result = $this->getResultByHtml($urlConfig, $data);
        }
        
        // 如果当前URL失败，尝试下一个URL
        if (empty($result)) {
            $this->configManager->updateCurrentUrl([]);
            return $this->getSearchResult($data, $index + 1);
        } else {
            // 更新当前使用的URL
            $this->configManager->updateCurrentUrl($urlConfig);
            return $result;
        }
    }
    
    /**
     * 通过JSON API获取搜索结果
     * @param array $config URL配置
     * @param array $data 搜索参数
     * @return array|null 搜索结果
     */
    private function getResultByJson($config, $data) {
        $url = trim($config['url'], '/');
        
        // 构建请求参数
        $params = [
            'q' => $data['q'],
            'language' => !empty($config['language']) ? $config['language'] : $data['language'],
            'time_range' => !empty($config['time_range']) ? $config['time_range'] : $data['time_range'],
            'safesearch' => !empty($config['safesearch']) ? $config['safesearch'] : $data['safesearch'],
            'categories' => !empty($config['categories']) ? $config['categories'] : $data['categories'],
            'theme' => !empty($config['theme']) ? $config['theme'] : $data['theme'],
            'format' => 'json'
        ];
        
        // 添加搜索引擎参数
        if (!empty($config['engines'])) {
            $data['engines'] = $config['engines'];
        }
        if (!empty($data['engines'])) {
            $params['engines'] = $data['engines'];
        }
        
        // 发送请求
        $response = $this->httpClient->request($url . '/search', $params, 'GET');
        
        // 解析JSON响应
        return json_decode($response, true);
    }
    
    /**
     * 通过HTML页面获取搜索结果
     * @param array $config URL配置
     * @param array $data 搜索参数
     * @return array|null 搜索结果
     */
    private function getResultByHtml($config, $data) {
        $url = trim($config['url'], '/');
        
        // 构建请求参数
        $params = [
            'q' => $data['q'],
            'language' => !empty($config['language']) ? $config['language'] : $data['language'],
            'time_range' => !empty($config['time_range']) ? $config['time_range'] : $data['time_range'],
            'safesearch' => !empty($config['safesearch']) ? $config['safesearch'] : $data['safesearch'],
            'categories' => !empty($config['categories']) ? $config['categories'] : $data['categories'],
            'theme' => !empty($config['theme']) ? $config['theme'] : $data['theme']
        ];
        
        // 添加搜索引擎参数
        if (!empty($config['engines'])) {
            $data['engines'] = $config['engines'];
        }
        if (!empty($data['engines'])) {
            $params['engines'] = $data['engines'];
        }
        
        // 发送请求
        $response = $this->httpClient->request($url . '/search', $params, 'POST');
        
        // 如果响应为空，返回失败
        if (empty($response)) {
            return null;
        }
        
        // 解析HTML响应
        return $this->parseHtmlResponse($response, $data['q']);
    }
    
    /**
     * 解析HTML响应
     * @param string $html HTML内容
     * @param string $query 搜索关键词
     * @return array|null 解析后的搜索结果
     */
    private function parseHtmlResponse($html, $query) {
        // 提取主要内容
        preg_match('|<div id="urls" role="main">(.*)<div id="backToTop">|isU', $html, $body);
        if (empty($body[1])) {
            return null;
        }
        
        // 分割文章
        $articles = explode('</article>', strip_tags($body[1], '<article>,<span>,<div>,<a>'));
        $results = [];
        
        // 解析每篇文章
        foreach ($articles as $article) {
            if (strpos($article, '<div class="engines">') < 0) {
                continue;
            }
            
            // 提取引擎信息
            preg_match('|<span>(.*)</span>|isU', $article, $engineBody);
            if (empty($engineBody[1])) {
                continue;
            }
            
            // 提取链接和标题
            $links = explode('</a>', $article);
            preg_match('|<a href="(.*)"|isU', $links[1], $urlMatch);
            $titleParts = explode('>', $links[1]);
            $contentParts = explode('<div', $links[2]);
            
            // 构建结果项
            $item = [
                'title' => trim($titleParts[1]),
                'url' => str_replace('&', '&', trim($urlMatch[1])),
                'engine' => trim($engineBody[1]),
                'content' => trim($contentParts[0])
            ];
            
            $results[] = $item;
        }
        
        // 如果没有结果，返回失败
        if (empty($results)) {
            return null;
        }
        
        // 返回结果数组
        return [
            'query' => $query,
            'results' => $results
        ];
    }
}